package cn.virens.common.boot.provider.auth;

import cn.virens.common.mybatis.entity.BaseModel;
import cn.virens.common.mybatis.entity.param.PageParam;
import cn.virens.common.mybatis.mapper.example.Example;
import cn.virens.common.util.core.Assert;
import cn.virens.common.util.exception.APIException;
import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.reflect.FieldUtil;
import org.dromara.hutool.core.text.StrUtil;

import java.util.Map;

public class ExampleUtil {
    /**
     * 删除全部使用
     */
    public static Example all() throws APIException {
        return Example.newInstance().and(c -> {
            c.andCondition("id > 0");
        });
    }

    public static String end(String value) throws APIException {
        return StrUtil.addPrefixIfNot(value, "%");
    }

    public static String start(String value) throws APIException {
        return StrUtil.addSuffixIfNot(value, "%");
    }

    public static Example key(Object value) throws APIException {
        return Example.of("`key`", Assert.isEmpty(id(value, "key")));
    }

    public static Example mac(Object value) throws APIException {
        return Example.of("`mac`", Assert.isEmpty(id(value, "mac")));
    }

    public static Example uuid(Object value) throws APIException {
        return Example.of("`uuid`", Assert.isEmpty(id(value, "uuid")));
    }

    public static Example code(Object value) throws APIException {
        return Example.of("`code`", Assert.isEmpty(id(value, "code")));
    }

    public static Example appid(Object value) throws APIException {
        return Example.of("`appid`", Assert.isEmpty(id(value, "appid")));
    }

    public static Example openid(Object value) throws APIException {
        return Example.of("`openid`", Assert.isEmpty(id(value, "openid")));
    }

    public static Example identity(Object value) throws APIException {
        return Example.of("`identity`", Assert.isEmpty(id(value, "identity")));
    }

    private static Example newInstance(String table, String tenant, String order) throws APIException {
        Example example = Example.newInstance();

        if (tenant != null && !tenant.isEmpty()) {
            example.and().andLike(feild(table, "tenant_id"), tenant);
        }
        if (order == null || order.isEmpty()) {
            example.desc(feild(table, "id"));
        }

        return example;
    }

    /**
     * 生成待租户条件的查询构建器
     */
    public static Example newInstance2(Map<String, Object> param, String table) throws APIException {
        return newInstance(table, AuthUtil.likeTenant2(param), null);
    }

    /**
     * 生成待租户条件的查询构建器
     */
    public static Example newInstance1(PageParam param, String table) throws APIException {
        return newInstance(table, AuthUtil.likeTenant1(param), param.getOrderBy());
    }

    /**
     * 生成待租户条件的查询构建器
     */
    public static Example newInstance0(String tenant, String table) throws APIException {
        return newInstance(table, AuthUtil.likeTenant0(tenant), null);
    }

    /**
     * 生成待租户条件的查询构建器
     */
    public static Example newInstance2(Map<String, Object> param) throws APIException {
        return newInstance2(param, null);
    }

    /**
     * 生成待租户条件的查询构建器
     */
    public static Example newInstance1(PageParam param) throws APIException {
        return newInstance1(param, null);
    }

    /**
     * 生成待租户条件的查询构建器
     */
    public static Example newInstance0(String tenant) throws APIException {
        return newInstance0(tenant, null);
    }

    /**
     * 获取指定字段的值
     *
     * @param value 来源对象/Map
     * @param key   字段名
     */
    public static Object id(Object value, String key) throws APIException {
        if (key != null && value instanceof BaseModel model) {
            return FieldUtil.getFieldValue(value, key);//
        }

        if (key != null && value instanceof Map<?, ?> map) {
            return MapUtil.getStr(map, key);//
        }

        return value;//
    }

    /**
     * 处理数据库字段（拼接数据库表名）
     */
    private static String feild(String table, String col) {
        if (table != null && !table.isEmpty()) {
            return table + "." + col;
        } else {
            return col;
        }
    }
}
